package com.bigflexlib.x.mx.rpc.remoting
{
	
	import com.bigflexlib.async.Deferred;
	import com.bigflexlib.x.mx.logging.Log.LogUtil;
	
	import mx.logging.ILogger;
	import mx.logging.Log;
	import mx.rpc.AbstractOperation;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;
	
	public class RemoteObjectUtil
	{
		
		private static var log:ILogger = LogUtil.getStandardLogger( RemoteObjectUtil );
				
		// Returns a Deferred, whose callback will be called with the raw service
		// result as paremeter.
		// 
		// In case of error, errback is called and an instance of mx.rpc.Fault
		// is passed
		public static function amf(endPoint:String, serviceName:String,
								   method:String, args:Array):Deferred 
		{
			if ( Log.isDebug() )
			{
				log.debug( "AMF {2}({3}) {0} {1} ", endPoint, serviceName, method, args.join(",") );
			}
			
			var resultListener:Function;
			var faultListener:Function;
			var r:RemoteObject = new RemoteObject();
			var canceller:Function = function(x:*):void 
			{
				r.removeEventListener(ResultEvent.RESULT, resultListener);
				r.removeEventListener(FaultEvent.FAULT, faultListener);
				try 
				{
					r.disconnect()
				}
				catch(e:*) { /* ignore errors*/}
			};
			var d:Deferred = new Deferred(canceller);
			r.endpoint = endPoint;
			r.destination = serviceName;
			resultListener = function(event:ResultEvent):void {
				r.removeEventListener(ResultEvent.RESULT, resultListener);
				r.removeEventListener(FaultEvent.FAULT, faultListener);
				d.callback(event.result);
			};
			faultListener = function(event:FaultEvent):void {
				r.removeEventListener(ResultEvent.RESULT, resultListener);
				r.removeEventListener(FaultEvent.FAULT, faultListener);
				d.errback(event.fault);
			};
			r.addEventListener(ResultEvent.RESULT, resultListener);
			r.addEventListener(FaultEvent.FAULT, faultListener);
			var op:AbstractOperation = r.getOperation(method);
			op.send.apply(op, args);
			return d;
		}
	}
}